package me.ak.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import me.ak.file.Saveable;
import me.ak.utils.BarCopy;
import me.ak.utils.CManip;

import org.jnbt.CompoundTag;
import org.jnbt.ListTag;
import org.jnbt.Tag;
import org.lwjgl.util.Point;


public class ScoreModel extends Model implements Saveable{
	
	private List<StaffInformation> staves = new ArrayList<StaffInformation>();
	private List<List<BarModel>> bars = new ArrayList<List<BarModel>>();
	private int barCount = 0;
	private ScoreInformation information = new ScoreInformation(); //TODO: load from file
	
	
	public void addBar() {
		for (List<BarModel> bar : bars) {
			bar.add(new BarModel(BarModel.createUID(), this));
		}
		barCount ++;
	}
	
	public List<List<BarModel>> getBars() {
		return Collections.unmodifiableList(bars);
	}
	
	/**
	 * 
	 * @return The length of the score in bars.
	 */
	public int getScoreLength() {
		return bars.get(0).size();
	}
	
	public BarModel getBarAt(int x, int y) {
		return bars.get(x).get(y);
	}
	
	public void addStaff() {
		staves.add(new StaffInformation(StaffInformation.createUID())); //TODO: update this code.
		List<BarModel> tlist = new ArrayList<BarModel>();
		for (int x = 0; x < barCount; x ++) {
			tlist.add(new BarModel(BarModel.createUID(), this));
		}
		bars.add(tlist);
	}
	
	public boolean setBarAt(BarModel bm, int x, int y) {
		if (bars.get(x).get(y) == null) {
			return false;
		}
		bars.get(x).remove(y);
		bars.get(x).add(y, bm);
		return true;
	}
	
	public void removeBarAt(int y) {
		for (List<BarModel> bar : bars) {
			bar.remove(y);
		}
		barCount --;
	}
	
	public Point getBarLocation(BarModel m) {
		for (List<BarModel> bml : bars) {
			for (BarModel bm : bml) {
				if (bm.getUID()==m.getUID()) {
					return new Point(bars.indexOf(bml), bml.indexOf(bm));
				}
			}
		}
		return null;
	}

	@Override
	public CompoundTag saveNBT() {
		//TODO: Save ScoreInfo
		HashMap<String, Tag> staffRoot = CManip.initMap();
		for (int i = 0; i < staves.size(); i++) {
			//TODO: save staff information
			HashMap<String, Tag> staffEntry = CManip.initMap();
			HashMap<String, CompoundTag> barInfo = CManip.initCMap();
			for (BarModel bm : bars.get(i)) {
				CompoundTag bar = bm.saveNBT();
				barInfo.put("Bar" + bm.getUID(), bar);
			}
			ListTag barInfoTag = new ListTag("Bars", CompoundTag.class, new ArrayList<Tag>(barInfo.values()));
			staffEntry.put("Bars", barInfoTag);
			//staffEntry.put(add staff information compound here!!!!!)
			
			staffRoot.put("Staff"+staves.get(i).UID, new CompoundTag("Staff", staffEntry));
		}
		ListTag staffRootTag = new ListTag("Staves", CompoundTag.class, new ArrayList<Tag>(staffRoot.values()));
		
		HashMap<String, Tag> score = CManip.initMap();
		score.put("Staves", staffRootTag);
		//score.put("ScoreInfo", dontForgetThis);
		return new CompoundTag("Score", score);
	}

	@Override
	public void readNBT(CompoundTag t) {
		
	}

}

	